package site.icesky.springboot.threadpool.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.*;
import site.icesky.springboot.threadpool.service.FileDeal;
import site.icesky.springboot.threadpool.util.FileUtil;
import site.icesky.springboot.threadpool.util.FtpUtil;

import java.util.List;

/**
 * @ClassName: ThreadPoolController <br>
 * @Description: 线程池测试 <br>
 * @Package: site.icesky.springboot.threadpool.controller <br>
 * @author: suitianmou <br>
 * @Date: 2020/8/15-11:02 <br>
 * @version: 1.0 <br>
 * @see <br>
 * @since (从产品的哪一个版本此类被添加进来 ( 可选))<br>
 * 修改历史: <br>
 * 修改时间             修改人           版本变更           修改说明<br>
 * -----------------------------------------------------<br>
 * <br>
 */

@RestController
public class ThreadPoolController {

    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolController.class);

    @Value("${ftp.ip}")
    private String ip;

    @Value("${ftp.port}")
    private int port;

    @Value("${ftp.userName}")
    private String userName;

    @Value("${ftp.password}")
    private String password;

    @Value("${ftp.passiveMode}")
    private boolean passiveMode;

    @Value("${ftp.remotePath}")
    private String remotePath;

    @Value("${ftp.localPath}")
    private String localPath;

    @Value("${config.thread-line}")
    private int threadLine;

    @Value("${config.thread-sleep}")
    private int threadSleepSec;

    @Value("${config.file-step}")
    private int fileStep;

    // 有多个，标记具体用哪个进行自动注入
    @Qualifier("taskExector")
    @Autowired
    ThreadPoolTaskExecutor threadExecutor;

    @RequestMapping(value = "/{file}")
    public String threadPoolDeal(@PathVariable String file) {

        FtpUtil ftpUtil = new FtpUtil();

        if (ftpUtil.connectServer(ip, port, userName, password, passiveMode) == false) {
            logger.error("连接远程服务器失败!!!");
            return "连接远程服务器失败";
        }
        ;

        List<String> fileList = ftpUtil.ls(remotePath);
        if (fileList == null) {
            logger.error("获取远程文件夹列表错误!!!");
            return "获取远程文件夹列表错误";
        }
        logger.info("远程文件夹列表如下:");
        for (String f : fileList) {
            logger.info(f);
        }

        logger.info("开始下载远程文件:" + remotePath + file  );
        if (ftpUtil.get(remotePath, file, localPath) == false) {
            logger.error("获取文件失败!!!");
            return "获取文件失败";
        }

        // 本地开启多个线程并发读取消息
        // 1. 获取文件总行数
        int fileLineNum = FileUtil.getFileLine(localPath + file);
        if (fileLineNum < 0) {
            logger.error("读取文件总行数失败!!!{}", fileLineNum);
            return "读取文件总行数失败";
        }

        // 2. 循环处理行数
        int startLine = 1;
        while (startLine <= fileLineNum) {
            FileDeal fileDeal = new FileDeal();

            fileDeal.setFileName(localPath + file);
            fileDeal.setLineNum(startLine);
            fileDeal.setFileStep(fileStep);

            logger.info("当前活跃线程数:[{}], 最大线程数:[{}]", threadExecutor.getActiveCount(), threadExecutor.getMaxPoolSize());

            /** 并发等待 **/
            while (threadExecutor.getActiveCount() >= (threadExecutor.getMaxPoolSize() - 5)) {
                logger.warn("线程池最大数目[{}][{}]超限， 等待[{}]秒后重试", threadExecutor.getActiveCount(),
                        threadExecutor.getMaxPoolSize() - 5, threadSleepSec / 1000);

                try {
                    Thread.sleep(threadSleepSec);
                } catch (InterruptedException e) {
                    logger.error("异常:", e);
                    return "等待异常!!!";
                }
            }

            // 执行线程任务
            threadExecutor.execute(fileDeal);

            // startLine叠加
            startLine = startLine + fileStep;
        }

        return "SUCCESS";
    }
}
